<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <title>濒危鸟类动物识别功能界面</title>
</head>
<link rel="stylesheet" href="{% static 'web/func_static/bootstrap3.4.1/css/bootstrap.min.css' %}">
{#引入bootstrap的js文件#}
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
}"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<style>
    body {
        background-image: url({% static 'web/func_static/bg.jpg'%});
        background-repeat: no-repeat;
        background-size: cover;

    }

    .main_box {
        border-radius: 15px;
        margin: auto auto;
        margin-top: 200px;
        /*display: flex;*/
        background-color: rgba(255, 255, 255, 0.8);
        box-shadow: 1px 2px 3px 4px rgba(0, 0, 0, 0.3);
        height: 800px;
        width: 1200px;
    }

    .main_box h2 {
        text-align: center;
        padding: 10px;

    }

    .preview_area {
        /*box-shadow: 1px 2px 3px 4px rgba(0, 0, 0, 0.3);*/
        height: 700px;
        width: 800px;
        display: flex;
        margin-left: 50px;
    }

    .button_area {
        height: 700px;
        width: 500px;
        /*box-shadow: 1px 2px 3px 4px rgba(0, 0, 0, 0.3);*/
        margin-left: 20px;
        align-content: center;
    }

    .btn {
        margin-left: 40px;
        margin-top: 60px;
        margin-bottom: 60px;
    }

    .img-preview {
        margin-top: 100px;
        margin-left: 20px;
        height: 200px;
        width: 300px;
        border: 1px solid black;
        text-align: center;
        border-radius: 5px;
        line-height: 200px;

    }

    .video-preview {
        margin-top: 50px;
        margin-left: 20px;
        height: 200px;
        width: 300px;
        border: 1px solid black;
        border-radius: 5px;
        text-align: center;
        line-height: 200px;
    {#align-content: center;#}
    }

    .camera-preview {
        margin-top: 100px;
        height: 450px;
        width: 400px;
        border: solid 1px black;
        border-left: 0;
        text-align: center;
        line-height: 450px;
        border-radius: 5px;
    }
</style>

<body>
<!--主容器-->
<div class="main_box">
    <!--    标题-->
    <h2>濒危鸟类动物识别</h2>
    <select class="form-select form-select-lg" aria-label="Default select example"
            style="margin-left: 910px;box-shadow: 0 1px 2px 3px rgba(0,0,0,0.1);font-size: 25px">
        <option selected>模型选择</option>
        <option value="1">yolov3</option>
        <option value="2">yolov5s</option>
        <option value="3">yolov8n</option>
    </select>
    <!--    媒体展示区域-->
    <div style="display: flex">
        <div class="preview_area">
            <div>
                <div class="img-preview" id="img-preview">图片展示区域</div>
                <div class="video-preview" id="video-preview">视频展示区域</div>

            </div>

            <div class="camera-preview" id="camera-preview">摄像头展示</div>
        </div>


        <!--        按钮点击区域-->
        <div class="button_area">
            <div></div>
            <!--            图片选择-->
            <input type="file" id="img-input" style="display: none;">
            <button class="btn btn-warning btn-lg" onclick="select_img()">选择图片</button>
            <!--            识别按钮区域-->
            <button class="btn btn-warning btn-lg" onclick="img_detect()">图片识别</button>

            <!--            视频选择-->
            <input type="file" id="video-input" style="display: none">
            <button class="btn btn-warning btn-lg" onclick="select_video()">选择视频</button>
            <button class="btn btn-warning btn-lg" onclick="video_detect()">视频识别</button>

            <!--            摄像头选择-->
            <input type="file" id="camera-input" style="display: none">
            <button class="btn btn-warning btn-lg" onclick="openCamera()">开摄像头</button>
            <button class="btn btn-warning btn-lg" onclick="camera_detect()">摄像识别</button>
        </div>
    </div>
    <!--使用bootstrap的警告框组件-->
    <div class="alert alert-warning row" role="alert"
         style="margin-top: 20px;margin-left: auto;margin-right: auto;display: block;width: 800px;"
         id="alert_box">
        <strong>注意：请确保上传的图片/视频清晰度足够，否则可能导致识别结果不准确。</strong>

    </div>
</div>

<script src="{% static 'web/func_static/axios/axios.min.js' %}"></script>

<script>
    <!--    图片预览容器逻辑-->
    function select_img() {
        // 获取文件输入框元素
        let fileInput = document.getElementById('img-input');
        // 监听文件选择事件
        fileInput.addEventListener('change', function () {
            // 通过fileInput.files[0]获取选择的文件对象
            let file = fileInput.files[0];

            // 创建一个 FileReader 对象
            let reader = new FileReader();

            // 读取文件内容，并在读取完成后执行回调函数
            reader.onload = function (e) {
                // 获取读取到的图片数据
                let imgData = e.target.result;

                // 将图片数据展示在img-preview元素中
                let imgPreview_div = document.getElementById('img-preview');
                let img = document.createElement("img")
                // 清空图片预览区域
                imgPreview_div.innerHTML = "";
                img.src = imgData;
                img.style.width = '100%';
                img.style.height = '100%';
                img.id = "img-cap";
                imgPreview_div.appendChild(img)
            };

            // 读取文件内容
            reader.readAsDataURL(file);
        });

        // 触发点击事件
        fileInput.click();
    }

    // 视频预览容器逻辑
    function select_video() {
        // 获取文件输入框元素
        let fileInput = document.getElementById('video-input');

        // 获取视频预览区域元素
        let videoPreview_div = document.getElementById('video-preview');

        // 清空视频预览区域
        videoPreview_div.innerHTML = "";

        // 监听文件选择事件
        fileInput.addEventListener('change', function () {
            // 通过fileInput.files[0]获取选择的文件对象
            let file = fileInput.files[0];

            // 创建一个 FileReader 对象
            let reader = new FileReader();

            // 读取文件内容，并在读取完成后执行回调函数
            reader.onload = function (event) {
                // 创建一个新的video标签插入到div容器中
                let videoElement = document.createElement('video');
                videoElement.src = event.target.result;
                videoElement.style.width = '100%';
                videoElement.style.height = '100%';
                videoElement.controls = true;
                videoElement.id = "video-cap";
                videoPreview_div.appendChild(videoElement);
            };

            // 读取视频文件内容
            reader.readAsDataURL(file);
        });

        // 触发点击事件
        fileInput.click();
    }

    // 摄像头容器展示逻辑
    function openCamera() {
        // 获取视频容器元素
        let cameraContainer = document.getElementById('camera-preview');
        cameraContainer.innerHTML = ""

        // 创建一个视频元素
        let camera_stream = document.createElement('video');
        camera_stream.autoplay = true;

        // 检查浏览器是否支持getUserMedia方法
        if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            // 请求打开摄像头
            navigator.mediaDevices.getUserMedia({video: true})
                .then(function (stream) {
                    // 将摄像头的视频流绑定到video元素上
                    camera_stream.srcObject = stream;
                    camera_stream.style.width = '100%';
                    camera_stream.style.width = '100%';
                    camera_stream.style.marginTop = "60px";
                    camera_stream.id = "camera-stream"
                    cameraContainer.appendChild(camera_stream);

                })
                .catch(function (error) {
                    console.error('打开摄像头失败: ', error);
                });
        } else {
            console.error('浏览器不支持getUserMedia方法');
        }
    }

    //     图片识别逻辑
    function img_detect() {
        // 获取要截图的div元素
        let img = document.getElementById('img-cap');
        console.log(img.src)

        // 获取图片的 base64 编码数据
        let imageData = img.src.split(',')[1];
        // 发送axios请求
        axios.post('api/img_api/', {
            image: imageData
        })
            .then(function (response) {
                console.log(response);
                alert("识别成功")
                let img_result = document.getElementById('img-cap')
                // 替换为识别结果
                img_result.src = 'data:image/jpeg;base64,' + response.data.image;
                // 放在警告框中显示，probs是识别结果的概率,name是识别结果的名称,position是识别结果的位置,每个值放一个p标签中
                let probs = response.data.probs
                let name = response.data.name
                let position = response.data.position
                let alert_box = document.getElementById('alert_box')
                alert_box.innerHTML = ""
                alert_box.innerHTML += "<strong>识别结果：</strong>"
                alert_box.innerHTML += "<p>名称：" + name + "</p>"
                alert_box.innerHTML += "<p>位置：" + position + "</p>"
                alert_box.innerHTML += "<p>置信度：" + probs + "</p>"


            })
            .catch(function (error) {
                alert("识别失败,可能是后端出现了问题")
                console.error(error);
            });
    }

    //  视频识别逻辑
    function video_detect() {
        let videoElement = document.getElementById('video-cap');
        videoElement.controls = true;

        let canvasElement = document.createElement('canvas');
        canvasElement.width = videoElement.videoWidth;
        canvasElement.height = videoElement.videoHeight;
        let context = canvasElement.getContext('2d');
        let result_container = document.getElementById("img-preview")
        result_container.innerHTML = ""
        // 创建一个img标签用来存储结果
        let result_img = document.createElement("img")
        result_img.style.height = "100%";
        result_img.style.width = "100%";
        result_container.appendChild(result_img)

        // 截取帧并发送帧给后端识别
        function captureFrame() {
            context.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);
            let imageData = canvasElement.toDataURL().split(',')[1];

            // 在这里执行你想要对每一帧图像做的操作
            // 使用axios发送请求
            axios.post('api/img_api/', {
                image: imageData
            })
                .then(function (response) {
                    // 请求成功处理逻辑
                    console.log(response.data);
                    result_img.src = 'data:image/jpeg;base64,' + response.data.image;
                    // 放在警告框中显示，probs是识别结果的概率,name是识别结果的名称,position是识别结果的位置,每个值放一个p标签中
                    let probs = response.data.probs
                    let name = response.data.name
                    let position = response.data.position
                    let alert_box = document.getElementById('alert_box')
                    alert_box.innerHTML = ""
                    alert_box.innerHTML += "<strong>识别结果：</strong>"
                    alert_box.innerHTML += "<p>名称：" + name + "</p>"
                    alert_box.innerHTML += "<p>位置：" + position + "</p>"
                    alert_box.innerHTML += "<p>置信度：" + probs + "</p>"
                })
                .catch(function (error) {
                    // 请求失败处理逻辑
                    console.log(error);
                });
            // ...

            // 请求下一帧
            setTimeout(captureFrame, 3000); // 每隔3秒请求一帧
        }

        // 开始截取帧
        function startCapture() {
            captureFrame();
        }

        // 停止截取帧
        function stopCapture() {
            cancelAnimationFrame(animationId);
        }

        let animationId;
        // 开始截取帧
        startCapture();

        // 视频结束时停止截取帧
        videoElement.addEventListener('ended', function () {
            stopCapture();
        })
    }

    // 摄像头检测逻辑
    function camera_detect() {
        // 获取返回的图像数据
        let img_data = get_camera_data();
        // 将图像数据转换为Base64字符串
        let base64_data = canvasToBase64(img_data);
        let imageData = base64_data.split(',')[1]; // 获取图片的 base64 编码数据
        // 发送POST请求给后端
        axios.post('/api/img_api/', {image: imageData})
            .then(response => {
                // 请求成功后的处理
                let resultElment = document.getElementById("img-preview")
                // 将图像重新赋值为识别结果
                resultElment.src = 'data:image/jpeg;base64,' + response.data.image;
                resultElment.style.width = '100%';
                resultElment.style.height = '100%';
                alert("识别成功！")
                let
                    })
            .catch(error => {
                // 请求失败后的处理
                console.error(error);
            });

    }

    // 获取摄像头的数据.
    function get_camera_data() {
        const video = document.getElementById("camera-stream");
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        // 在Canvas上绘制视频帧
        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        // 获取Canvas上的图像数据
        const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
        return imageData
    }

    // 转图像为base64
    function canvasToBase64(canvasData) {
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        canvas.width = canvasData.width;
        canvas.height = canvasData.height;
        context.putImageData(canvasData, 0, 0);
        return canvas.toDataURL('image/jpeg');
    }


</script>
</body>
</html>